import collections
import socket
import errno
import asyncore

BUFFLEN = 8192

carriers = collections.deque()

class Handler(asyncore.dispatcher):
    def __init__(self, sock, recv_queue, send_queue):
        self._recv_queue = recv_queue
        self._send_queue = send_queue
        asyncore.dispatcher.__init__(self, sock = sock)

    def readable(self):
        return True

    def writable(self):
        return bool(self._send_queue)

    def _read(self):
        buff = []
        while True:
            try:
                t = self.recv(BUFFLEN)
            except socket.error, e:
                if e.errno == errno.EAGAIN or e.errno == errno.EWOULDBLOCK:
                    break
            if not t:
                break
            print '%s RECV:' % (self.getpeername(),), len(t)
            buff.append(t)
        return buff

    def handle_read(self):
        buff = self._read()
        self._recv_queue.extend(buff)

    def handle_write(self):
        while bool(self._send_queue):
            buff = self._send_queue.popleft()
            print '%s SEND:' % (self.getpeername(),), len(buff)
            self.sendall(buff)

    def handle_close(self):
#        lrq, rlq = carriers.popleft()
        lrq, rlq = self._recv_queue, self._send_queue
#        lrq.clear()
#        rlq.clear()
        carriers.append((lrq, rlq))
        self.close()

class TgwHandler(Handler):
    def __init__(self, *a, **kw):
        Handler.__init__(self, *a, **kw)
        self._handshaked = False
        self._handshake_buff = ''

    def handle_read(self):
        if self._handshaked:
            return Handler.handle_read(self)
        buff = self._read()
        self._handshake_buff += ''.join(buff)
        self._handshake()

    def _handshake(self):
        if '\r\n\r\n' not in self._handshake_buff:
            return
        t = self._handshake_buff.split('\r\n\r\n', 1)[1]
        if t:
            self._recv_queue.append(t)
        self._handshaked = True
        print 'TGW hand shaked.'

class LocalServer(asyncore.dispatcher):
    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.bind((host, port))
        self.listen(1)

    def handle_accept(self):
        if not carriers:
            self.close()
        lrq, rlq = carriers.popleft()
        sock, addr = self.accept()
        Handler(sock, lrq, rlq)

class RemoteServer(LocalServer):
    def handle_accept(self):
        sock, addr = self.accept()
        lrq = collections.deque()
        rlq = collections.deque()
        TgwHandler(sock, rlq, lrq)
        carriers.append((lrq, rlq))

if __name__ == '__main__':
    ls = LocalServer('localhost', 10000)
    rs = RemoteServer('0.0.0.0', 8010)
    asyncore.loop()

